import time
from pref import prefs
from pyo import *
import OscServer
from getScripts import finalDict as modulesDict
from AudioFx import AudioSlot
# print modulesDict

class EmptyFx(AudioSlot):
    """
    example audio process
    """
    name = "Empty"
    ctrls = ["None","None","None"]
    info = ["None","None","None", "Empty"]
    def __init__(self):
        AudioSlot.__init__(self, "fx",self.name,self.ctrls)
        self.output = self.input

class EmptyMod(AudioSlot):
    """
    example audio process
    """
    name = "Empty"
    ctrls = ["None","None","None"]
    info = ["None","None","None", "Empty"]
    def __init__(self):
        AudioSlot.__init__(self, "mod",self.name,self.ctrls)

empty = {"fx":EmptyFx,"mod":EmptyMod}


class OscClass(object):
    """
    parent class for Osc com, 6 sliders, 4 menus, 3 texts, 4 onoff buttons
    
    new:
        dual menu for selection: files and classes in files


    args : 
        addressPrepend: name prepended to osc adresses (for object with lemur container)
        name: 


    """
    def __init__(self, addressPrepend, modulation,type):
        self.type = type
        self.addressPrepend = addressPrepend
        self.osc = OscServer.OscCtrls(addressPrepend)

        # modules files
        self.allModules = modulesDict[type] # all dicts of files here
        self.modules = {i:{"class":None} for i in range(19)}
        # self.moduleNames
        self.files = self.allModules.keys() # need to build list of files for lemur
        self.files.insert(0, "NONE")
        if len(self.files)<19:
            for i in range(20-len(self.files)):
                self.files.append("NONE")
        # on list selection build list of classes for lemur
        # by default load empty slot and send slot list of empty slot and nones
        
        self.modulation = modulation # dict with other module's mods
        # audio
        self.audioIn = Sig([0 for i in range(prefs["channels"])]) #next version audio dict like modulation
        # self.modIn = [Sig(0) for i in range(3)] # get from modu lation dict
        self.modInChoo = [Sig(0) for i in range(3)] # get from modu lation dict
        self.audioOut = Sig(self.audioIn)
        self.modOut = Sig(0)

        self.slot = empty[type]
        self.slotMute = 1

        # // OSC Controls
        self.ctrl1 = self.osc.newAudio("ctrl1",[0],"/audio","/ctrl1/x","lemur1",[0])
        self.ctrl2 = self.osc.newAudio("ctrl2",[1],"/audio","/ctrl2/x","lemur1",[0])
        self.ctrl3 = self.osc.newAudio("ctrl3",[2],"/audio","/ctrl3/x","lemur1",[0])
        self.modAmnt1 = 2*self.osc.newAudio("modAmnt1",[3],"/audio","/modamount1/x","lemur1",[0.5])-1
        self.modAmnt2 = 2*self.osc.newAudio("modAmnt2",[4],"/audio","/modamount2/x","lemur1",[0.5])-1
        self.modAmnt3 = 2*self.osc.newAudio("modAmnt3",[5],"/audio","/modamount3/x","lemur1",[0.5])-1
        self.osc.newData("menuSelectionMain","i",self.oscSlotSel, "/slotselect/selection", "/slotselect/selection", "lemur1")
        self.osc.newData("groupSelect","i",self.groupSel, "/groupSelect/selection", "/groupSelect/selection", "lemur1")
        self.osc.newData("modsel1","i",self.modsel1, "/modselect1/selection", "/modselect1/selection", "lemur1")
        self.osc.newData("modsel2","i",self.modsel2, "/modselect2/selection", "/modselect2/selection", "lemur1")
        self.osc.newData("modsel3","i",self.modsel3, "/modselect3/selection", "/modselect3/selection", "lemur1")
        self.osc.newData("globalOnOff","i",self.globalOnOff, "/globalOnOff/x", "/globalOnOff/x", "lemur1")
        self.osc.newData("enableMod1","i",self.enableMod1, "/enableMod1/x", "/enableMod1/x", "lemur1")
        self.osc.newData("enableMod2","i",self.enableMod2, "/enableMod2/x", "/enableMod2/x", "lemur1")
        self.osc.newData("enableMod3","i",self.enableMod3, "/enableMod3/x", "/enableMod3/x", "lemur1")
        self.osc.newDataOut("fillSlotMenu", "s"*19, "/slotselect/setSelection", "lemur1")
        self.osc.newDataOut("fillGroupMenu", "s"*19, "/groupSelect/setSelection", "lemur1")
        self.osc.newDataOut("fillMods", "s"*len(self.modulation), "/setMods", "lemur1")
        self.osc.newDataOut("ctrlNames", "ssss", "/setCtrlNames", "lemur1")

        self.mctrl1 = Clip(self.ctrl1+(Abs((self.modAmnt1>0)-self.ctrl1)*self.modAmnt1*self.modInChoo[0]),0,1)
        self.mctrl2 = Clip(self.ctrl2+(Abs((self.modAmnt2>0)-self.ctrl2)*self.modAmnt2*self.modInChoo[1]),0,1)
        self.mctrl3 = Clip(self.ctrl3+(Abs((self.modAmnt3>0)-self.ctrl3)*self.modAmnt3*self.modInChoo[2]),0,1)
        # // INITOSC

        self.osc.send("fillGroupMenu",self.files)
        self.oscInitCtrls()
        self.oscSendModulationNames()
        self.osc.send("ctrlNames",["None","None","None","Empty"])
        time.sleep(0.1)

    def groupSel(self, selected):
        sel = self.files[int(selected)]
        if not sel == "NONE":
            self.modules = self.allModules[sel]
            sendList = [self.modules[i]["name"] for i in range(len(self.modules))]
            sendList.insert(0, "NONE")
            if len(sendList)<19:
                for i in range(20-len(sendList)):
                    sendList.append("NONE")
            self.osc.send("fillSlotMenu",sendList)
            self.osc.send("menuSelectionMain", 0)
            
            
            print self.files
            print "selected file"
        
        # group selected: send all names and put groups dict into self.modules
        
    def oscSlotSel(self, selected):
        # function inits class into slot from modules dict
        # sets audio inputs and modulation in
        # sets audio controls (modulation+Ctrl)
        # gets audio output and mod out(to modout dict/classes'smodout variable>modoutdict)
        # when modules changes
        # put sig(0) into inputs (audio and mod)
        # 
        # _DONE_ init class from dict into slot variable
        # _DONE_  send control names to lemur
        # _DONE_ connect audio or mods (if) inouts
        # _ (audio init stuff: mute fx?, fadein?)

        # deconnect audio from last module?
        if int(selected)> 0:
            selected -= 1
            if int(selected)<len(self.modules):
                self.slot = self.modules[int(selected)]["class"]()

                if self.slot.type == "fx":
                    self.slot.setAudioIn(self.audioIn)
                    if self.slotMute:
                        self.audioOut.setValue(self.slot.getAudioOut())

                else:
                    self.modOut.setValue(self.slot.getMod())
                # here get init value and send to 

                initvals = self.slot.getInitVals()
                for i in range(3):
                    self.osc.send("ctrl%i" % (i+1),initvals[i])

                names = self.slot.getAllInfo()
                self.osc.send("ctrlNames",names)
                self.slot.setCtrls([self.mctrl1,self.mctrl2,self.mctrl3])


    def setAudio(self, audio):
        self.audioIn.setValue(audio)

    def getMod(self):
        if self.type == "mod":
            return self.modOut

    def getAudio(self):
        return self.audioOut

    def modsel1(self, selected):
        if selected:
            self.modInChoo[0].setValue(self.modulation[int(selected)]["audio"])
        else:
            self.modInChoo[0].setValue(Sig(0))

    def modsel2(self, selected):
        if selected:
            self.modInChoo[1].setValue(self.modulation[int(selected)]["audio"])
        else:
            self.modInChoo[1].setValue(Sig(0))

    def modsel3(self, selected):
        if selected:
            self.modInChoo[2].setValue(self.modulation[int(selected)]["audio"])
        else:
            self.modInChoo[2].setValue(Sig(0))

    def globalOnOff(self, onoff):
        self.slotMute = onoff
        if onoff:
            self.slot.turnOn()
            if self.type == "fx":
                self.audioOut.setValue(self.slot.getAudioOut())
            elif self.type == "mod":
                self.modOut.setValue(self.slot.getMod())
        else:
            self.slot.turnOff()
            if self.type == "fx":
                self.audioOut.setValue(self.audioIn)
            elif self.type == "mod":
                self.modOut.setValue(Sig(0))


    def enableMod1(self, onoff):
        self.modInChoo[0].setMul(onoff)
    
    def enableMod2(self, onoff):
        self.modInChoo[1].setMul(onoff)
            
    def enableMod3(self, onoff):
        self.modInChoo[2].setMul(onoff)

    def oscSendModulationNames(self):
        self.osc.send("fillMods",[self.modulation[i]["name"] for i in range(len(self.modulation))])


    def oscInitCtrls(self):
        self.osc.send("ctrl1",[0])
        self.osc.send("ctrl2",[0])
        self.osc.send("ctrl3",[0])
        self.osc.send("modAmnt1",[0.5])
        self.osc.send("modAmnt2",[0.5])
        self.osc.send("modAmnt3",[0.5])
        self.osc.send("globalOnOff",[1])
        self.osc.send("enableMod1",[1])
        self.osc.send("enableMod2",[1])
        self.osc.send("enableMod3",[1])
        self.osc.send("menuSelectionMain", 0)
        self.osc.send("groupSelect", 0)
        self.osc.send("modsel1", 0)
        self.osc.send("modsel2", 0)
        self.osc.send("modsel3", 0)